package com.thudojsc.canvasengine;

import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;

import com.thudojsc.canvasengine.entity.Node;
import com.thudojsc.canvasengine.entity.Scene;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;

import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class GameSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
	
	private int mWidth = 0;
	private int mHeight = 0;
	
	private UpdateThread mUpdateThread = null;
	
	private Scene mCurrentScene = null;
	
	/* Khoi tao*/
	public GameSurfaceView(Context context) {
		super(context);
		getHolder().addCallback(this);
		getHolder().setFormat(PixelFormat.TRANSPARENT);
		
		this.mUpdateThread = new UpdateThread(getHolder(), this);
	}
	

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		this.mWidth = width;
		this.mHeight = height;
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		mUpdateThread.setRunning(true);
		mUpdateThread.start();
	}
	
	public int getScreenWidth() {
		return mWidth;
	}
	
	public int getScreenHeight() {
		return mHeight;
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		/* CLEAR SCREEN */
		Paint paint = new Paint();
		paint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
		canvas.drawPaint(paint);
		paint.setXfermode(new PorterDuffXfermode(Mode.SRC));
		
		
		if (mCurrentScene != null)
			mCurrentScene.draw(canvas);
	}
	
	public void runWithScene(final Scene pScene) {
		final SurfaceHolder holder = getHolder();
		
		synchronized (holder) {
			this.mCurrentScene = pScene;
		}
	}
	
	protected void onUpdate(final float dt) {
		if (mCurrentScene != null) 
			mCurrentScene.update(dt);
		
	}
	
	/*--------------------TOUCH PROCESS----------------------*/
	
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		final SurfaceHolder holder = getHolder();
		synchronized (holder) {	
			
		}
		
		return true;
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		boolean retry = true;
		
		mUpdateThread.setRunning(false);
		
		while (retry) {
			try {
				mUpdateThread.join();
				retry = false;
			} catch (Exception e) {
				
			}
		}
	}
	

	public class UpdateThread extends Thread {
		private SurfaceHolder mSurfaceHolder = null;
		private GameSurfaceView mDirectory = null;
		
		private boolean mRunning = false;
		
		private long mLastTime = 0;
		
		public UpdateThread(final SurfaceHolder pSurfaceHolder, final GameSurfaceView pDirectory) {
			this.mSurfaceHolder = pSurfaceHolder;
			this.mDirectory = pDirectory;
		}
		
		public void setRunning(final boolean isRunning) {
			this.mRunning = isRunning;
		}
		
		@Override
		public void run() {
			Canvas canvas;
			
			while (mRunning) {
				canvas = null;
				
				
				
				try {
					canvas = mSurfaceHolder.lockCanvas(null);
					
					synchronized (mSurfaceHolder) {
						/* UPDATE VIEW*/
						
						final long now = System.currentTimeMillis();
						
						if (mLastTime == 0)
							mDirectory.onUpdate(0);
						else {	
							mDirectory.onUpdate((float)(now -mLastTime) / 1000f);
						}
						
						mLastTime = now;
						
						/* DRAW  */
						mDirectory.onDraw(canvas);
					}
				} finally {
					
					if (canvas != null) {
						mSurfaceHolder.unlockCanvasAndPost(canvas);
					}
				}
			}
		}
	}
	
	public interface IEngineCallback {
		public void onComplete(final Engine pEngine);
	}
}
